#pragma once

#include <cstdint>
#include  <vector>
#include <iostream>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <wchar.h>

#include <d2d1.h>
#include <d2d1helper.h>
#include <dwrite.h>
#include <wincodec.h>

class BScanImageException : public std::runtime_error
{
public:
	BScanImageException(const HRESULT code, const std::string& what_arg) :std::runtime_error(what_arg), errorCode(code) {};
	~BScanImageException() {};
	HRESULT getErrorCode() const { return errorCode; }
	static constexpr uint32_t FacilityBScanImage = 3500;
	static constexpr HRESULT FailedInit = 0x80000000 | 3500 << 16 | 1;
private:
	HRESULT errorCode;
};

//This class  output Bscan  png image
//This class throws BScanImageException if it  happen problem in the process.
//exsample:
//	BScanImage img(img_width, img_height);
//	img.setBscan(anything_bscan_data, scan_depth* scan_number, scan_depth);
//	img.outputImage(file_path);
class BScanImage
{
public:
	BScanImage(uint32_t width, uint32_t height);
	~BScanImage();
	void setBscan(const float* & b_scan, size_t size, size_t depth);
	void setBscan(float* & b_scan, size_t size, size_t depth);
	void outputImage(const WCHAR* path);
	float getMaxIntensity() const;
	void setMaxIntensity(float max_intensity);
	float getMinIntensity() const;
	void setMinIntensity(float min_intensity);
private:
	//direct2D member
	IWICImagingFactory *wic_factory_ = nullptr;
	ID2D1Factory *d2d_factory_ = nullptr;
	IDWriteFactory *dwrite_factory_ = nullptr;
	IWICBitmap *wic_bitmap_ = nullptr;
	ID2D1RenderTarget *render_target_ = nullptr;
	IDWriteTextFormat *text_format_ = nullptr;

	ID2D1BitmapRenderTarget* bscan_render_target_ = nullptr;
	ID2D1Bitmap* bscan_image_ = nullptr;

	//data
	float** bscan_data_=nullptr;
	uint32_t bscan_size_ = 0;
	uint32_t depth_ = 0;
	std::vector<uint32_t> buffer_;
	std::vector<uint32_t> color_list;
	float max_intensity_=30;
	float min_intensity_ =-20;

	bool is_init_ = false;
	void rendering() const;
	void ReleaseAll();
};


